/**
 * 对JSON文件进行增删改查
 */

const fs = require('fs');

// 创建目录
const dirCache = {};
function mkdir(filePath) {
    const arr = filePath.split('/');
    let dir = arr[0];
    for (let i = 1; i < arr.length; i++) {
        if (!dirCache[dir] && !fs.existsSync(dir)) {
            dirCache[dir] = true;
            fs.mkdirSync(dir);
        }
        dir = dir + '/' + arr[i];
    }
    fs.writeFileSync(filePath, '');
}

/**
 * 增
 * 写入json文件
 * @param filePath 文件路径
 * @param params   写入的数据【对象或数组】
 */
function addJsonFile(filePath, params) {
    return new Promise((resolve, reject) => {
        if (!fs.existsSync(filePath)) {  // 该路径不存在
            mkdir(filePath);
            console.log('创建JSON文件');
        }

        //先将json文件读出来
        fs.readFile(filePath, function (err, data) {
            if (err) {
                reject({code: 500, msg: '数据新增失败'});
                return console.error(err);
            }
            let result = data.toString();//将二进制的数据转换为字符串
            if(result) {
                result = JSON.parse(result);//将字符串转换为json对象
            } else {
                result= {
                    data: [],
                    total: 0
                };
            }

            // 将要写入的数据与读取的数据合并
            if (params instanceof Array) {  // 是数组
                for (let item of params) {
                    result.data.push(item);
                }
            } else {  // 单纯的对象
                result.data.push(params);//将传来的对象push进数组对象中
            }
            // console.log(result.data);

            // 写入文件
            result.total = result.data.length;//总条数，为以后的分页打基础
            // let str = JSON.stringify(result); //因为nodejs的写入文件只认识字符串或者二进制数，所以把json对象转换成字符串重新写入json文件中
            let str = JSON.stringify(result, null, '\t');  // JSON字符串的格式化
            fs.writeFile(filePath, str, function (err) {
                if (err) {
                    reject({code: 500, msg: '数据新增失败'});
                    return console.error(err);
                }
                resolve({code: 200, msg: '数据新增成功'});
                console.log('----------数据新增成功-------------');
            })
        })
    })

}


/**
 * 删
 * 根据id删除json文件中的数据项
 * @param filePath  文件名
 * @param id        所删除数据项的id
 */
function deleteJsonById(filePath, id) {
    return new Promise((resolve, reject) => {
        fs.readFile(filePath, function (err, data) {
            if (err) {
                reject({code: 500, msg: '数据删除失败'});
                return console.error(err);
            }
            let result = data.toString();
            result = JSON.parse(result);
            //把数据读出来删除
            for (let i = 0; i < result.data.length; i++) {
                if (id == result.data[i].id) {
                    //console.log(result.data[i])
                    result.data.splice(i, 1);
                }
            }
            // console.log(result.data);

            result.total = result.data.length;
            let str = JSON.stringify(result, null, '\t');
            //然后再把数据写进去
            fs.writeFile(filePath, str, function (err) {
                if (err) {
                    reject({code: 500, msg: '数据删除失败'});
                    return console.error(err);
                }
                resolve({code: 200, msg: '数据删除成功'});
                console.log("----------数据删除成功------------");
            })
        })
    })
}



/**
 * 改
 * 根据id修改json数据
 * @param filePath  文件名
 * @param id        所修改数据项的id
 * @param params    所修改数据项的值
 */
function updateJsonById(filePath, id, params) {
    return new Promise((resolve, reject) => {
        fs.readFile(filePath, function (err, data) {
            if (err) {
                reject({code: 500, msg: '数据修改失败'});
                return console.error(err);
            }
            let result = data.toString();
            result = JSON.parse(result);
            //把数据读出来,然后进行修改
            for (let i = 0; i < result.data.length; i++) {
                if (id == result.data[i].id) {
                    for (let key in params) {
                        if (typeof result.data[i][key] !=='undefined') {
                            result.data[i][key] = params[key];
                        }
                    }
                }
            }

            // console.log(result.data);

            result.total = result.data.length;
            let str = JSON.stringify(result, null, '\t');
            fs.writeFile(filePath, str, function (err) {
                if (err) {
                    reject({code: 500, msg: '数据修改失败'});
                    return console.error(err);
                }
                resolve({code: 200, msg: '数据修改成功'});
                console.log('----------数据修改成功-----------');
            })
        })
    })
}



/**
 * 查
 * 通过传回来的页码和每页数据条数，进行分页模拟
 * @param filePath  文件名
 * @param currPage  当前页码，比如第一页传1，第二页传2
 * @param pageSize  每页多少条数据
 */
function getJSONByPagination(filePath, currPage=1, pageSize=10){
    return new Promise((resolve, reject) => {
        //读取全部数据
        fs.readFile(filePath, function(err,data){
            if(err){
                reject({code: 500, msg: '数据查询失败'});
                return console.error(err);
            }
            let dataList = data.toString();
            dataList = JSON.parse(dataList);

            // 返回分页数据
            const length = dataList.data.length;
            let start = (currPage<1 || pageSize<0) ? 0 : pageSize*(currPage-1);
            let end = (currPage*pageSize < length) ? currPage*pageSize : length;
            const result = dataList.data.reverse().slice(start, end);
            // console.log(result);
            resolve({
                code: 200, msg: '数据查询成功',
                data: {
                    list: JSON.stringify(result),
                    currPage,
                    pageSize,
                    total: dataList.total,
                }
            });
            console.log('------------数据查询成功------------');
            console.log(`一共查询到${result.length}条数据`);
        })
    })
}

/**
 * 查
 * 通过 id 获取数据
 * @param filePath  文件名
 * @param id  数据的id
 */
function getJSONByID(filePath, id=1){
    return new Promise((resolve, reject) => {
        fs.readFile(filePath, function(err,data){
            if(err){
                reject({code: 500, msg: '数据查询失败'});
                return console.error(err);
            }
            let result = data.toString();
            result = JSON.parse(result);
            //console.log(result.data);

            const length = result.data.length;
            for(let i=0; i<length; i++) {
                if(result.data[i].id == id) {
                    resolve({code: 200, msg: '数据查询成功', data: JSON.stringify(result.data[i])});
                    console.log('------------数据查询成功------------');
                    console.log(`一共查询到1条数据`);
                    return ;
                }
            }

            reject({code: 201, msg: '该条数据不存在'});
            console.log('------------数据查询失败------------');
        })
    })
}



/**
 * 专用于更新访问量
 * @param filePath
 * @param id
 * @param params
 * @returns {Promise<unknown>}
 */
function updateViewsJsonById(filePath, id) {
    return new Promise((resolve, reject) => {
        fs.readFile(filePath, function (err, data) {
            if (err) {
                reject({code: 500, msg: '数据修改失败'});
                return console.error(err);
            }
            let result = data.toString();
            result = JSON.parse(result);
            let res= {};
            for (let i = 0; i < result.data.length; i++) {
                if (id == result.data[i].id) {
                    if(result.data[i].views) {
                        result.data[i].views= parseInt(result.data[i].views) + 1;
                    } else {
                        result.data[i].views= 1;
                    }
                    res= result.data[i];
                }
            }

            // console.log(result.data);

            result.total = result.data.length;
            let str = JSON.stringify(result, null, '\t');
            fs.writeFile(filePath, str, function (err) {
                if (err) {
                    reject({code: 500, msg: '数据修改失败'});
                    return console.error(err);
                }
                resolve({code: 200, msg: '数据修改成功', data: JSON.stringify(res)});
                console.log('----------数据修改成功-----------');
            })
        })
    })
}


/**
 * 查找所有的数据
 * @param filePath
 * @returns {Promise<unknown>}
 */
function getJSONAllData(filePath){
    return new Promise((resolve, reject) => {
        //读取全部数据
        fs.readFile(filePath, function(err,data){
            if(err){
                reject({code: 500, msg: '数据查询失败'});
                return console.error(err);
            }
            let result = data.toString();

            // 返回所有数据
            resolve({code: 200, msg: '数据查询成功', data: result});
            console.log('------------数据查询成功------------');
        })
    })
}
// 获取数据条数
function getJSONDataTotal(filePath){
    return new Promise((resolve, reject) => {
        //读取全部数据
        fs.readFile(filePath, function(err,data){
            if(err){
                reject({code: 500, msg: '数据查询失败'});
                return console.error(err);
            }
            let result = data.toString();
            result= JSON.parse(result);
            // 返回所有数据
            resolve({code: 200, msg: '数据查询成功', data: {total: result.total}});
            console.log('------------数据查询成功------------');
        })
    })
}


/**
 * 根据条件分页查询数据
 * @param filePath
 * @param keys
 * @param values
 * @returns {Promise<unknown>}
 */
function getJSONByCondition(filePath, conditions, currPage=1, pageSize=10){
    return new Promise((resolve, reject) => {
        //读取全部数据
        fs.readFile(filePath, function(err,data){
            if(err){
                reject({code: 500, msg: '数据查询失败'});
                return console.error(err);
            }
            let dataList = data.toString();
            dataList = JSON.parse(dataList);

            // 返回分页数据
            let dataList1= dataList.data;
            let selectedList = [];
            for(let i=dataList1.length-1; i>=0; i--) {
                let mark = true;
                for(let key in conditions) {
                    if(dataList1[i][key] !== conditions[key]) {
                        mark= false;
                        break;
                    }
                }
                if(mark) {
                    selectedList.push(dataList1[i])
                }
            }

            let start = (currPage<1 || pageSize<0) ? 0 : pageSize*(currPage-1);
            let end = (currPage*pageSize < selectedList.length) ? currPage*pageSize : selectedList.length;
            const result = selectedList.slice(start, end);
            // console.log(result);
            resolve({
                code: 200, msg: '数据查询成功',
                data: {
                    list: JSON.stringify(result),
                    currPage,
                    pageSize,
                    total: selectedList.length,
                }
            });
            console.log('------------数据查询成功------------');
            console.log(`一共查询到${result.length}条数据`);
        })
    });
}

// 根据条件获取指定条数的数据
function getAllJSONByCondition(filePath, conditions, size=1){
    return new Promise((resolve, reject) => {
        //读取全部数据
        fs.readFile(filePath, function(err,data){
            if(err){
                reject({code: 500, msg: '数据查询失败'});
                return console.error(err);
            }
            let dataList = data.toString();
            dataList = JSON.parse(dataList);

            // 返回分页数据
            let dataList1= dataList.data;
            let selectedList = [];
            for(let i=dataList1.length-1; i>=0; i--) {
                let mark = true;
                for(let key in conditions) {
                    if(dataList1[i][key] !== conditions[key]) {
                        mark= false;
                        break;
                    }
                }
                if(mark) {
                    selectedList.push(dataList1[i])
                }
            }

            size = (size < selectedList.length) ? size : selectedList.length;
            const result = selectedList.slice(0, size);
            resolve({
                code: 200, msg: '数据查询成功',
                data: JSON.stringify(result)
            });
            console.log('------------数据查询成功------------');
            console.log(`一共查询到${result.length}条数据`);
        })
    });
}



/**
 * 通过 username 获取用户数据
 * @param filePath  文件名
 * @param username 用户名
 */
function getJSONByUsername(filePath, username){
    return new Promise((resolve, reject) => {
        fs.readFile(filePath, function (err, data) {
            if (err) {
                reject({code: 500, msg: '数据查询失败'});
                return console.error(err);
            }
            let result = data.toString();
            result = JSON.parse(result);
            const length = result.data.length;
            for (let i = 0; i < length; i++) {
                if (result.data[i].username === username || result.data[i].phone === username || result.data[i].email === username) {
                    resolve({code: 200, msg: '数据查询成功', data: JSON.stringify(result.data[i])});
                    console.log('------------数据查询成功------------');
                    // console.log(`一共查询到1条数据`);
                    return;
                }
            }

            reject({code: 201, msg: '该条数据不存在'});
            console.error('------------数据查询失败------------');
        })
    })
}

/**
 * 用于查询用户名、手机号、邮箱是否已存在
 * @param filePath
 * @param keys
 * @param values
 * @returns {Promise<unknown>}
 */
function getJSONByKeys(filePath, keys, values){
    return new Promise((resolve, reject) => {
        fs.readFile(filePath, function(err,data){
            if(err){
                reject({code: 500, msg: '数据查询失败'});
                return console.error(err);
            }
            let result = data.toString();
            result = JSON.parse(result);
            const length = result.data.length;
            for(let i=0; i<length; i++) {
                if(result.data[i][keys[0]] === values[0]) {
                    resolve({code: 202, msg: '用户名已被使用'});
                    return ;
                }
                if(result.data[i][keys[1]] === values[1]) {
                    resolve({code: 202, msg: '手机号已被使用'});
                    return ;
                }
                if(result.data[i][keys[2]] === values[2]) {
                    resolve({code: 202, msg: '邮箱已被使用'});
                    return ;
                }
            }

            reject({code: 201, msg: '该条数据不存在'});
            console.error('------------数据查询失败------------');
        })
    })
}




const mockPath = './mock/'
module.exports = {
    addJsonFile: (filePath, params)=>addJsonFile(mockPath+filePath, params),
    deleteJsonById,
    updateJsonById: (filePath, id, params)=>updateJsonById(mockPath+filePath, id, params),
    getJSONByPagination: (filePath, currPage, pageSize)=>getJSONByPagination(mockPath+filePath, currPage, pageSize),
    getJSONById: (filePath, id)=>getJSONByID(mockPath+filePath, id),

    updateViewsJsonById: (filePath, id)=>updateViewsJsonById(mockPath+filePath, id),
    getJSONAllData: (filePath)=>getJSONAllData(mockPath+filePath),
    getJSONDataTotal: (filePath)=>getJSONDataTotal(mockPath+filePath),
    getJSONByCondition: (filePath, conditions, currPage, pageSize)=>getJSONByCondition(mockPath+filePath, conditions, currPage, pageSize),
    getAllJSONByCondition: (filePath, conditions, size)=>getAllJSONByCondition(mockPath+filePath, conditions, size),
    getJSONByUsername:  (filePath, username)=>getJSONByUsername(mockPath+filePath, username),
    getJSONByKeys: (filePath, key, value)=>getJSONByKeys(mockPath+filePath, key, value),
}

